package platformio

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/godbus/dbus/v5"
)

const (
	PlatformIODir = ".platformio"
	HomeStateFile = "homestate.json"
	AppStateFile  = "appstate.json"
)

var PLATFORM_IO_PREFIX = ""

func init() {
	PLATFORM_IO_PREFIX, _ = os.UserHomeDir()
	PLATFORM_IO_PREFIX = filepath.Join(PLATFORM_IO_PREFIX, PlatformIODir)
}

func Err(err error) *dbus.Error {
	return &dbus.Error{
		Name: err.Error(),
	}
}

// .platfromio
type PIO interface {

	// appstate.json、homestate.json
	GetAppStateJsonFile() (content string, err *dbus.Error)
	GetHomeStateJsonFile() (content string, err *dbus.Error)

	// packages、platforms
	GetPackageNames() (names []string, err *dbus.Error)
	GetPlatformNames() (names []string, err *dbus.Error)

	// platforms/*/
	GetPlatformInfo(platform string) (err *dbus.Error)
	GetPackageInfo(package0 string) (err *dbus.Error)

	// platforms/*/boards/*、platforms/*/examples/
	GetPlatformBoards(platform string) (boards []string, err *dbus.Error)
	GetPlatformExamples(platform string) (examples []string, err *dbus.Error)

	// platforms/*/.piopm、platforms/*/platform.json
	GetPlatformPioPmFile(platform string) (content string, err *dbus.Error)
	GetPlatformJsonFile(platform string) (content string, err *dbus.Error)
}

type PlatformIOPath string

// pio *PlatformIO PIO
type PlatformIO struct {
	PlatformIOPath
}

func NewPlatformIO(path PlatformIOPath) PIO {
	return &PlatformIO{
		PlatformIOPath: path,
	}
}

// appstate.json、homestate.json
func (pio *PlatformIO) GetAppStateJsonFile() (content string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), AppStateFile)
	b, _ := os.ReadFile(path)
	content = string(b)
	return
}

func (pio *PlatformIO) GetHomeStateJsonFile() (content string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), HomeStateFile)
	b, _ := os.ReadFile(path)
	content = string(b)
	return
}

// packages、platforms
func (pio *PlatformIO) GetPackageNames() (names []string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "packages")

	de, err0 := os.ReadDir(path)
	if err0 != nil {
		return names, Err(err0)
	}

	for _, v := range de {
		names = append(names, v.Name())
	}
	return
}

func (pio *PlatformIO) GetPlatformNames() (names []string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "platforms")

	de, err0 := os.ReadDir(path)
	if err0 != nil {
		return names, Err(err0)
	}

	for _, v := range de {
		names = append(names, v.Name())
	}

	return
}

// platforms/*/
func (pio *PlatformIO) GetPlatformInfo(platform string) (err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "platforms", platform)
	fmt.Printf("path: %v\n", path)
	return
}

func (pio *PlatformIO) GetPackageInfo(package0 string) (err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "packages", package0)
	fmt.Printf("path: %v\n", path)
	return
}

// platforms/*/boards/*、platforms/*/examples/
func (pio *PlatformIO) GetPlatformBoards(platform string) (boards []string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "platforms", platform, "boards")
	de, err0 := os.ReadDir(path)
	if err0 != nil {
		return boards, Err(err0)
	}

	for _, v := range de {
		board := filepath.Join(path, v.Name())
		boards = append(boards, board)
	}

	return
}

func (pio *PlatformIO) GetPlatformExamples(platform string) (examples []string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "platforms", platform, "examples")
	de, err0 := os.ReadDir(path)
	if err0 != nil {
		return examples, Err(err0)
	}

	for _, v := range de {
		example := filepath.Join(path, v.Name())
		examples = append(examples, example)
	}
	return
}

// platforms/*/.piopm、platforms/*/platform.json
func (pio *PlatformIO) GetPlatformPioPmFile(platform string) (content string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "platforms", platform, ".piopm")
	b, _ := os.ReadFile(path)
	content = string(b)
	return
}

func (pio *PlatformIO) GetPlatformJsonFile(platform string) (content string, err *dbus.Error) {
	path := filepath.Join(string(pio.PlatformIOPath), "platforms", platform, "platform.json")
	b, _ := os.ReadFile(path)
	content = string(b)
	return
}
